package com.ff.kvm.mall.helper.impl;

import com.ff.kvm.common.dv.es.ProductESDV;
import com.ff.kvm.common.dv.lv.SecondDV;
import com.ff.kvm.common.eunm.ChangeTypeEnum;
import com.ff.kvm.common.eunm.OrderTypeEnum;
import com.ff.kvm.common.eunm.ProductTypeEnum;
import com.ff.kvm.common.eunm.UserLvEnum;
import com.ff.kvm.common.util.Constants;
import com.ff.kvm.common.util.ConvertUtil;
import com.ff.kvm.common.util.MyUtil;
import com.ff.kvm.dao.model.*;
import com.ff.kvm.mall.helper.DirectIncomeHelper;
import com.ff.kvm.mall.service.*;
import com.ff.kvm.team.consumer.TeamConsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class DirectIncomeHelperImpl implements DirectIncomeHelper {

    @Autowired
    private OrderService orderService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderPriceService orderPriceService;

    @Autowired
    private UserLvService userLvService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private OrderItemsService orderItemsService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private TeamConsumer teamConsumer;

    @Autowired
    private ProductService productService;

    @Autowired
    private AchieLogService achieLogService;

    @Override
    public void incomeOrLvUp(String orderNo) {
        if(redisService.getCache(Constants.INCOME_SWITCH).equals("0")){
            return;
        }
        Order order = orderService.findOrderByNo(orderNo);
        if(order.getType() == OrderTypeEnum.NORMAL.type()){
            productIncome(order.getUserId(),order.getId(),orderNo);
        }else if(order.getType() == OrderTypeEnum.ROB.type()){
            productRobIncome(order.getUserId(),order.getId(),orderNo);
        }else if(order.getType() == OrderTypeEnum.GIFTBOX.type()){
            //判断是否升级身份
            userService.upLv(order.getUserId(),order.getId());
            giftBoxIncome(order.getUserId(),order.getId(),orderNo);
        }else if(order.getType() == OrderTypeEnum.HOT.type()){
            saveAchieLog(order.getUserId(),order.getId(),orderNo);
        }

    }

    private void saveAchieLog(int userId, int orderId,String orderNo) {
        //热销商品
        OrderItems orderItems = orderItemsService.finOrderItems(orderId).get(0);
        achieLogService.saveLog(userId,MyUtil.float2(orderItems.getPrice()*orderItems.getQuantity()),1,orderNo,orderId);
    }

    private void giftBoxIncome(int userId,int orderId,String orderNo) {
        Product product = productService.findProductNormalByOrderId(orderId);
        achieLogService.saveLog(userId,product.getPrice(),1,orderNo,orderId);
        //保存es
        productService.sendGiftBoxES(userId,orderId,product);
        double discout = Double.valueOf(redisService.getCache(Constants.GIFT_BOX_INCOME));
        double income = MyUtil.float2(discout*product.getPrice());
        while (true){
            User upUser = userService.findUpUserById(userId);
            if(upUser == null || income == 0){
                break;
            }
            UserLv upUserLv = userLvService.findUserLvByLv(upUser.getLv());
            double amount = upUserLv.getAmount();
            if(income <= amount){
                accountService.income(upUser.getId(),income, ChangeTypeEnum.GIFT_BOX_RETURN.type(),orderNo);
                break;
            }else{
                accountService.income(upUser.getId(),amount, ChangeTypeEnum.GIFT_BOX_RETURN.type(),orderNo);
            }

            //游客不返利
            if(upUser.getLv() == UserLvEnum.VISITOR.type()){
                break;
            }
            //剩余的返利上滑
            Integer upUpLv = userService.findUpUserLvById(upUser.getId());
            if(upUpLv != null && upUpLv <= upUser.getLv()){
                break;
            }
            userId = upUser.getId();
            income = MyUtil.float2(income - amount);
        }

    }

    private void productRobIncome(int userId,int orderId,String orderNo) {
        double discout = Double.valueOf(redisService.getCache(Constants.PRODUCT_INCOME_BONUS).split("-")[1]);
        OrderItems orderItems = orderItemsService.finOrderItems(orderId).get(0);
        achieLogService.saveLog(userId,MyUtil.float2(orderItems.getPrice()*orderItems.getQuantity()),0,orderNo,orderId);
        //抢购商品按照支付价的固定10%，按照等级返利一级
        double total = MyUtil.float2(orderItems.getPrice()*orderItems.getQuantity()*discout);
        User upUser = userService.findUpUserById(userId);
        if(upUser == null){
            return;
        }
        accountService.income(upUser.getId(),total, ChangeTypeEnum.PRODUCT_ROB_RETURN.type(),orderNo);
    }

    private void productIncome(int userId,int orderId,String orderNo) {
        OrderPrice orderPrice = orderPriceService.findOrderPriceByOrderId(orderId);
        achieLogService.saveLog(userId,orderPrice.getAmount(),0,orderNo,orderId);
        String[] discout = redisService.getCache(Constants.PRODUCT_INCOME_BONUS).split("-");
        double total = 0d;
        List<OrderItems> list = orderItemsService.finOrderItems(orderId);
        for (OrderItems orderItems : list){
            //普通商品按照原价35%，按照等级返利一级
            double price = productService.getPriceById(orderItems.getProductId());
            total += price*orderItems.getQuantity();
        }
        //记录商品团队绩效
        saveProductES(userId,orderId,MyUtil.float2(total*Double.valueOf(discout[2])));

        int lv = userService.getUserLvByUserId(userId);
        User upUser = userService.findUpUserById(userId);
        if(upUser == null){
            return;
        }
        if(lv > upUser.getLv()){
            return;//上级小于下级身份，不返利
        }

        if(lv == upUser.getLv() && lv != UserLvEnum.VISITOR.type()){
            return;//都为大众会员的时候可以返利，其他等级均不返
        }
        total = total*Double.valueOf(discout[0]);
        UserLv upUserLv = userLvService.findUserLvByLv(upUser.getLv());
        Map<Object,Object> map = ConvertUtil.jsonToMap(upUserLv.getSecond(),SecondDV.class,"lv","point");
        if(map.containsKey(lv)){
            accountService.income(upUser.getId(),MyUtil.float2(total*(Double) map.get(lv)), ChangeTypeEnum.PRODUCT_NORMAL_RETURN.type(),orderNo);
        }
    }

    private void saveProductES(int userId,int orderId,double total) {
        ProductESDV productESDV = new ProductESDV();
        productESDV.setUserId(userId);
        productESDV.setTotal(total);
        productESDV.setOrderId(orderId);
        productESDV.setCreateTime(new Date());
        teamConsumer.addProduct(productESDV);
    }


}
